package core;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;

public class ParticleSystem
{
	private static int genericMaterialCount = 0;
	
	private String name;
	
	private ArrayList<Particle> particles;
	private Material material;
	
	private boolean collision;
	
	private float maxAccX;
	private float minAccX;
	private float maxAccY;
	private float minAccY;

	private int maxLifetime;
	private int minLifetime;
	private int maxLifetimeDiff;
	private int minLifetimeDiff;
	
	private int minVelocityX;
	private int maxVelocityX;
	private int minVelocityY;
	private int maxVelocityY;
	
	private boolean randomizeAccX;
	private boolean randomizeAccY;
	private boolean randomizeLifeTime;
	private boolean randomizeLifeTimeDiff;
	private boolean randomizeVelocityX;
	private boolean randomizeVelocityY;
	
	public ParticleSystem(String name) throws IOException
	{
		particles = new ArrayList<Particle>();
		material = new Material("Generic_Material_" + genericMaterialCount++);
		
		this.name = name;
		
		maxAccX = 0.2f;
		minAccX = -0.2f;
		maxAccY = 0.2f;
		minAccY = -0.2f;
		maxLifetime = 120;
		minLifetime = 275;
		maxLifetimeDiff = 2;
		minLifetimeDiff = 1;
		maxVelocityX = 2;
		minVelocityX = 0;
		maxVelocityY = 3;
		minVelocityY = 0;
		randomizeAccX = false;        
		randomizeAccY = false;        
		randomizeLifeTime = false;    
		randomizeLifeTimeDiff = false;
		randomizeVelocityX = false;   
		randomizeVelocityY = false;   
		
		collision = true;
	}
	
	public String getName()
	{
		return name;
	}
	
	public void setName(String n)
	{
		name = n;
	}
	
	public void setAccelerationX(float min, float max)
	{
		if (min >= max && randomizeAccX)
		{
			maxAccX = 0.2f;
			minAccX = -0.2f;
		}
		else
		{
			maxAccX = max;
			minAccX = min;
		}
	}
	
	public void setAccelerationY(float min, float max)
	{
		if (min >= max && randomizeAccY)
		{
			maxAccY = 0.2f;
			minAccY = -0.2f;
		}
		else
		{
			maxAccY = max;
			minAccY = min;
		}
	}
	
	public void setLifetimeDiff(int min, int max)
	{
		if (min >= max && randomizeLifeTimeDiff)
		{
			maxLifetimeDiff = 2;
			minLifetimeDiff = 1;
		}
		else
		{
			maxLifetimeDiff = max;
			minLifetimeDiff = min;
		}
	}
	
	public void setLifetime(int min, int max)
	{
		if (min >= max && randomizeLifeTime)
		{
			maxLifetime = 275;
			minLifetime = 120;
		}
		else
		{
			maxLifetime = min;
			minLifetime = max;
		}
	}
	
	public void setVelocityX(int min, int max)
	{
		if (min >= max && randomizeVelocityX)
		{
			maxVelocityX = 2;
			minVelocityX = 0;
		}
		else
		{
			maxVelocityX = max;
			minVelocityX = min;
		}
	}
	
	public void setVelocityY(int min, int max)
	{
		if (min >= max && randomizeVelocityY)
		{
			maxVelocityY = 3;
			minVelocityY = 0;
		}
		else
		{
			maxVelocityY = max;
			minVelocityY = min;
		}
	}
	
	public void setCollisionEnabled(boolean c)
	{
		collision = c;
	}
	
	public void setRandomizeAccelerationX(boolean a)
	{
		randomizeAccX = a;
	}
	
	public void setRandomizeAccelerationY(boolean a)
	{
		randomizeAccY = a;
	}
	
	public void setRandomizeVelocityX(boolean a)
	{
		randomizeVelocityX = a;
	}
	
	public void setRandomizeVelocityY(boolean a)
	{
		randomizeVelocityY = a;
	}
	
	public void setRandomizeLifetime(boolean a)
	{
		randomizeLifeTime = a;
	}
	
	public void setRandomizeLifetimeDiff(boolean a)
	{
		randomizeLifeTimeDiff = a;
	}
	
	public void setMaterial(Material mat)
	{
		material = mat;
	}
	
	public void addParticle(int x, int y, int n)
	{
		for (int i = 0; i < n; i++)
		{
			Particle p = new Particle(new Vector2D(new Random().nextInt(16) - 8 + x, new Random().nextInt(12) - 6 + y));
			p.setAccelerationX(minAccX, maxAccX);
			p.setAccelerationY(minAccY, maxAccY);
			p.setLifetime(minLifetime, maxLifetime);
			p.setLifetimeDiff(minLifetimeDiff, maxLifetimeDiff);
			p.setVelocityX(minVelocityX, maxVelocityX);
			p.setVelocityY(minVelocityY, maxVelocityY);
			p.setRandomizeAccelerationX(randomizeAccX);
			p.setRandomizeAccelerationY(randomizeAccY);
			p.setRandomizeLifetime(randomizeLifeTime);
			p.setRandomizeLifetimeDiff(randomizeLifeTimeDiff);
			p.setRandomizeVelocityX(randomizeVelocityX);
			p.setRandomizeVelocityY(randomizeVelocityY);
			p.setCollisionEnabled(collision);
			p.setMaterial(material);
			p.create();
			particles.add(p);
		}
	}
	
	public int getParticleCount()
	{
		return particles.size();
	}
	
	public void update(int w, int h, ArrayList<Rectangle> obst)
	{
		for (int i = 0; i < particles.size(); i++)
		{
			Particle p = particles.get(i);
			if (p == null || p.isDead())
			{
				particles.remove(i);
				i--;
			}
			else
				p.update(w, h, obst);				
		}
	}
	
	public void render(Graphics g)
	{
		for (int i = 0; i < particles.size(); i++)
		{
			Particle p = particles.get(i);
			if (p != null)
				p.draw(g);
		}
	}
}
